package com.joker.aigc.blog.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joker.aigc.blog.domain.dto.ArticleDTO;
import com.joker.aigc.blog.domain.dto.ArticleQueryDTO;
import com.joker.aigc.blog.domain.mapstruct.ArticleMapstruct;
import com.joker.aigc.blog.domain.po.ArticlePO;
import com.joker.aigc.blog.domain.vo.ArticleVO;
import com.joker.aigc.blog.mapper.ArticleMapper;
import com.joker.aigc.blog.service.ArticleService;
import com.joker.aigc.domain.entity.User;
import com.joker.aigc.mapper.UserMapper;
import com.joker.aigc.utils.AssertUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author luckincoffee
 * @description 针对表【article(文章表)】的数据库操作Service实现
 * @createDate 2025-01-05 17:09:39
 */
@Slf4j
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, ArticlePO> implements ArticleService {


    @Resource
    private ArticleMapstruct articleMapstruct;


    @Resource
    private UserMapper userMapper;


    @Override
    public ArticleVO getArticleById(Long id) {
        ArticlePO articlePO = getById(id);
        return articleMapstruct.toVO(articlePO);
    }


    @Override
    public Page<ArticleVO> getArticlePage(ArticleQueryDTO articleQueryDTO) {
        // 构建查询条件
        LambdaQueryWrapper<ArticlePO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Objects.nonNull(articleQueryDTO.getId()), ArticlePO::getId, articleQueryDTO.getId())
                .eq(Objects.nonNull(articleQueryDTO.getUid()), ArticlePO::getCreatedBy, articleQueryDTO.getUid())
                .like(Objects.nonNull(articleQueryDTO.getTitle()), ArticlePO::getTitle, articleQueryDTO.getTitle())
                .between(Objects.nonNull(articleQueryDTO.getStartDate()), ArticlePO::getCreateTime, articleQueryDTO.getStartDate(), articleQueryDTO.getEndDate())
                .eq(Objects.nonNull(articleQueryDTO.getStatus()), ArticlePO::getStatus, articleQueryDTO.getStatus())
                .orderBy(true, false, ArticlePO::getCreateTime);
        // 分页查询
        Page<ArticlePO> page = new Page<>(articleQueryDTO.getPageNum(), articleQueryDTO.getPageSize());
        Page<ArticlePO> pagePO = page(page, wrapper);
        List<Long> userIds = pagePO.getRecords().stream().map(ArticlePO::getCreatedBy).distinct().collect(Collectors.toList());
        List<User> users = userMapper.selectBatchIds(userIds);
        return (Page<ArticleVO>) pagePO.convert(articlePO -> {
            ArticleVO vo = articleMapstruct.toVO(articlePO);
            vo.setUserName(users.stream().filter(user -> user.getId().equals(articlePO.getCreatedBy())).findFirst().map(User::getUsername).orElse(""));
            return vo;
        });
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ArticleVO addArticle(ArticleDTO articleDTO) {
        Assert.notNull(articleDTO, "文章信息不能为空");
        AssertUtil.isTrue(StringUtils.isNotBlank(articleDTO.getTitle()), "文章标题不能为空");
        AssertUtil.isTrue(StringUtils.isNotBlank(articleDTO.getContent()), "文章内容不能为空");
        AssertUtil.isTrue(Objects.nonNull(articleDTO.getCreatedBy()), "用户信息不能为空");
        ArticlePO articlePO = articleMapstruct.toEntity(articleDTO);
        // 根据uuid和user_id进行查询。查询是不是保存草稿
        if (Objects.nonNull(articlePO.getUuid())) {
            ArticlePO old = getOne(new LambdaQueryWrapper<ArticlePO>().
                    eq(ArticlePO::getUuid, articlePO.getUuid())
                    .eq(ArticlePO::getCreatedBy, articlePO.getCreatedBy()));
            if (Objects.nonNull(old)) {
                articlePO.setId(old.getId());
            }
        }
        // 有可能是保存草稿
        if (Objects.isNull(articlePO.getId())) {
            save(articlePO);
        } else {
            updateById(articlePO);
        }
        return articleMapstruct.toVO(articlePO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateArticle(ArticleDTO articleDTO) {
        Assert.notNull(articleDTO, "文章信息不能为空");
        AssertUtil.isTrue(StringUtils.isNotBlank(articleDTO.getTitle()), "文章标题不能为空");
        AssertUtil.isTrue(StringUtils.isNotBlank(articleDTO.getContent()), "文章内容不能为空");
        ArticlePO old = getById(articleDTO.getId());
        Assert.notNull(old, "文章不存在");
        ArticlePO articlePO = articleMapstruct.toEntity(articleDTO);
        updateById(articlePO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteArticle(Long id) {
        removeById(id);
    }
}




